package cn.com.cetccst.distribution.mqtt;

import android.content.Context;
import android.util.Log;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import cn.com.cetccst.mqtt.ISSMqttClient;
import cn.com.cetccst.mqtt.MqttManager;
import cn.com.cetccst.tools.log.CommonLogger;

public class DistributionMqtt {

    private static DistributionMqtt instance;
    public ISSMqttClient mqttClient;
    private final Map<String, Set<Callback>> topicCallbacks = new HashMap<>();
    private final Map<String, MqttManager.MessageCallback> msgCallbacks = new HashMap<>();

    public interface Callback {
        void onMessageArrived(String message);
    }

    private DistributionMqtt(Context context, String url) {
        if (mqttClient == null) {
            mqttClient = new MqttManager.Builder(context, url, state -> CommonLogger.info(state.toString())).build();

            //反射注册全部的topic
            Field[] fields = Topics.class.getDeclaredFields();
            for (Field field : fields) {
                if (java.lang.reflect.Modifier.isStatic(field.getModifiers()) &&
                        java.lang.reflect.Modifier.isFinal(field.getModifiers())) {
                    try {
                        String topic = (String) field.get(null);

                        msgCallbacks.computeIfAbsent(topic, k -> (MqttManager.MessageCallback) message -> {
                            Set<Callback> callbacks = topicCallbacks.get(topic);
                            if (callbacks != null) {
                                for (Callback callback : callbacks) {
                                    callback.onMessageArrived(message);
                                }
                            }
                        });

                        mqttClient.subscribeTopic(topic, msgCallbacks.get(topic));
                    } catch (IllegalAccessException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
            mqttClient.connect();
        }
    }

    public static void initialize(Context context, String url) {
        if (instance == null) {
            instance = new DistributionMqtt(context, url);
        }
    }

    public static DistributionMqtt get() {
        return instance;
    }

    public void subscribe(String topic, Callback callback) {
        Set<Callback> callbacks = topicCallbacks.computeIfAbsent(topic, k -> new HashSet<>());
        callbacks.add(callback);
    }

    public void unsubscribe(String topic, Callback callback) {
        Set<Callback> callbacks = topicCallbacks.get(topic);
        if (callbacks != null) {
            callbacks.remove(callback);
        }
    }
}
